<?php 
/**
 * +----------------------------------------------------------------------+
 * php23种设计模式实现-享元模式
 * Author：微信公众号：yuantanphp
 * 获取更多资源，技术答疑，项目合作请关注微信公众号：yuantanphp
 * +----------------------------------------------------------------------+
 */
namespace Flyweight;
//抽象类-定义生产摩托车流水线标准
interface MotorcycleProduce
{
    //发动机方法
    public  function addEngine();
    //车身方法
    public  function addBody();
    //车轮方法
    public  function addWhell();
    //喷漆方法
    public  function setBodyColor(string $color);
    //获取摩托
    public  function getMotor();
}
//摩托车产品本身
class MotocycleProduct{
    private $motor = [
        "engine"=>"",
        "body"=>"",
        "whell"=>"",
        "bodyColor"=>"blue"
    ];
    //新增发动机零部件
    public function addEngine($engine){
        $this->motor["engine"] = $engine;
    }
    public function addBody($body){
        $this->motor["body"] = $body;
    }
    public function addWhell($whell){
        $this->motor["whell"] = $whell;
    }
    public function setBodyColor(string $color){
        $this->motor["bodyColor"] = $color;
    }
    //获取完整摩托对象
    public function getMotor(){
        return $this->motor;
    }
}
/**
 * 踏板摩托组装
 */
class motorcycleScooter implements MotorcycleProduce
{
    public function __construct()
    {
        $this->motor = new MotocycleProduct();
    }
    public function addEngine()
    {
        $this->motor->addEngine("踏板摩托-发动机已装好");
    }
    public function addBody(){
        $this->motor->addBody("踏板摩托-车身已装好");
    }
    public function addWhell(){
        $this->motor->addWhell("踏板摩托-车轮已装好");
    }
    public function setBodyColor($color){
        $this->motor->setBodyColor($color);
    }
    public function getMotor(){
        return $this->motor->getMotor();
    }
}
class MotorcycleStraddle implements MotorcycleProduce{
    public function __construct()
    {
        $this->motor = new MotocycleProduct();
    }
    function addEngine()
    {
        $this->motor->addEngine("跨骑摩托-发动机已装好");
    }
    function addBody()
    {
        $this->motor->addBody("跨骑摩托-车身已装好");
    }
    function addWhell()
    {
        $this->motor->addWhell("跨骑摩托-车轮已装好");
    }
    function setBodyColor($color){
        $this->motor->setBodyColor($color);
    }
    function getMotor()
    {
        return $this->motor->getMotor();
    }
}
/**
 * 享元工厂模式
 */
class FlyweightFactory
{
    private $flyweights = [];

    public function getFlyweight($number) : MotorcycleProduce
    {
        if (!array_key_exists($number, $this->flyweights)) {
            $this->flyweights[$number] = new motorcycleScooter();
        }
        return $this->flyweights[$number];
    }
}
//非享元模式
echo "来自跨期摩托车生产线<br>";
$motorcycleStraddle = new MotorcycleStraddle;
$motorcycleStraddle->addEngine();
$motorcycleStraddle->addBody();
$motorcycleStraddle->addWhell();
$motorcycleStraddle->setBodyColor("red");
$motorStraddle = $motorcycleStraddle->getMotor();
var_dump($motorStraddle);
echo "<br>";
//享元模式
$number = 0;
$flyweightFactory = new FlyweightFactory();
$motorcycleScooter = $flyweightFactory->getFlyweight($number++);
$motorcycleScooter->addEngine();
$motorcycleScooter->addBody();
$motorcycleScooter->addWhell();
$motorcycleScooter->setBodyColor("red");
$motorScooter = $motorcycleScooter->getMotor();
echo "来自生产线{$number}号<br>";
var_dump($motorScooter);
echo "<br>";
$motorcycleScooter = $flyweightFactory->getFlyweight($number);
$motorcycleScooter->addEngine();
$motorcycleScooter->addBody();
$motorcycleScooter->addWhell();
$motorcycleScooter->setBodyColor("blue");
$motorScooter = $motorcycleScooter->getMotor();
echo "来自生产线{$number}号<br>";
var_dump($motorScooter);
echo "<br>";
$motorcycleScooter = $flyweightFactory->getFlyweight($number++);
$motorcycleScooter->addEngine();
$motorcycleScooter->addBody();
$motorcycleScooter->addWhell();
$motorcycleScooter->setBodyColor("green");
$motorScooter = $motorcycleScooter->getMotor();
echo "来自生产线{$number}号<br>";
var_dump($motorScooter);
echo "<br>";
$motorcycleScooter = $flyweightFactory->getFlyweight($number);
$motorcycleScooter->addEngine();
$motorcycleScooter->addBody();
$motorcycleScooter->addWhell();
$motorcycleScooter->setBodyColor("orange");
$motorScooter = $motorcycleScooter->getMotor();
echo "来自生产线{$number}号<br>";
var_dump($motorScooter);
echo "<br>";
